Const {
  Const.strokeWidth = 1.5
  Const.padding = 20.0
}

Colors {
  Colors.black = rgba(0.0, 0.0, 0.0, 1.0)
  Colors.lightBlue = rgba(0.1, 0.1, 0.9, 0.2)
  Colors.lightYellow = rgba(0.95, 0.96, 0.92, 0.5)
}

Set x {
    x.shape = Circle {
        color : Colors.lightBlue
        strokeColor : Colors.black
        strokeStyle : "solid"
        strokeWidth : 1.0
        rotation : 0.0
    }

    x.text    = Text {
      string : x.label
      rotation : 0.0
    }

    -- TODO
    x.labelFn = ensure contains(x.shape, x.text)
    LOCAL.layering = x.shape below x.text
}

-- Selector ordering matters!
Set x; Set y
where IsSubset(x, y) {
  LOCAL.containFn = ensure contains(y.shape, x.shape, 10.0)
  -- y.sizeFn    = ensure smallerThan(x.shape, y.shape)
  LOCAL.outsideFn = ensure outsideOf(y.text, x.shape, 1.0)
  LOCAL.layering = x.shape above y.shape
}

Map f
where From(f, X, Y); IsSubset(X, R1); IsSubset(Y, R2)
with Set X; Set Y; Set R1; Set R2 {
  f.padding = 20.0

    f.shape = Arrow {
      startX : R1.shape.x + (R1.shape.side) / 2.0 + f.padding
      startY : R1.shape.y
      endX : R2.shape.x - (R2.shape.side) / 2.0 - f.padding
      endY : R2.shape.y
      thickness : 2.0
      color : Colors.black
        -- style : "curved"
    }

    f.text     = Text {
      -- Doesn't seem to work after the first resample. Is the server updating f.text.h on resample?
      -- x : (f.shape.startX + f.shape.endX) / 2.0
      -- y : (f.shape.startY + f.shape.endY) / 2.0 + 1.1 * f.text.h
      string : f.label
      rotation : 0.0
    }

    f.labelFn  = encourage centerLabel(f.shape, f.text, 5.0)
    -- f.centerFn = encourage centerArrow(f.shape, R1.shape, R2.shape)
}

Set `U` {
    override `U`.shape.strokeStyle = "dashed"
    override `U`.shape.strokeWidth = Const.strokeWidth
}

Set `V` {
    override `V`.shape.strokeStyle = "dashed"
    override `V`.shape.strokeWidth = Const.strokeWidth
}

-- TODO: use subtyping for reals?
Set `Rn` {
    override `Rn`.shape = Square {
      -- Works but is slow
      -- x : -100.0
      -- y = 0.0
      color : Colors.lightYellow
      rotation : 0.0
      strokeWidth : Const.strokeWidth
      strokeColor : Colors.black
    }

    `Rn`.text.x = `Rn`.shape.x + `Rn`.shape.side / 2.0 - Const.padding
    `Rn`.text.y = `Rn`.shape.y + `Rn`.shape.side / 2.0 - Const.padding

    delete `Rn`.labelFn
    delete `Rn`.outsideFn
    `Rn`.minSizeFn = ensure minSize(`Rn`.shape)
    `Rn`.maxSizeFn = ensure maxSize(`Rn`.shape)
}

Set `Rm`
with Set `Rn` {
    -- TODO: factor this block out
    override `Rm`.shape = Square {
        color : Colors.lightYellow
        y : `Rn`.shape.y
        x : `Rn`.shape.x + 400.0
        side  : `Rn`.shape.side
        rotation : 0.0
        strokeWidth : 1.0
        strokeColor : Colors.black
    }

    `Rm`.text.x = `Rm`.shape.x + `Rm`.shape.side / 2.0 - Const.padding
    `Rm`.text.y = `Rm`.shape.y + `Rm`.shape.side / 2.0 - Const.padding

    delete `Rm`.labelFn
    delete `Rm`.outsideFn

    -- This doesn't seem to work
    --    `Rm`.posFn = encourage topRightOf(`Rm`.text, `Rm`.shape)
    `Rm`.minSizeFn = ensure minSize(`Rm`.shape)
    `Rm`.maxSizeFn = ensure maxSize(`Rm`.shape)
}
